package com.openlogic.logic.service.logic.impl;

import java.util.Date;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;

import javax.validation.constraints.NotNull;

import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson2.JSON;
import com.openlogic.api.logic.entity.RuleModelDeploy;
import com.openlogic.common.core.enums.DictEnum;
import com.openlogic.common.core.exception.ServiceException;
import com.openlogic.common.core.utils.DateUtils;
import com.openlogic.common.core.web.domain.model.LoginUser;
import com.openlogic.common.logic.constants.RuleConstants;
import com.openlogic.common.logic.constants.RuleTypeConstants;
import com.openlogic.common.logic.decision.table.engine.XDecisionTableEngine;
import com.openlogic.common.logic.decision.table.model.DecisionTable;
import com.openlogic.common.logic.decision.table.model.DecisionTableResultVo;
import com.openlogic.common.security.utils.SecurityUtil;
import com.openlogic.logic.mapper.logic.RuleDecisionTableMapper;
import com.openlogic.logic.service.logic.RuleDecisionTableService;

/**
 * @ClassName: RuleDecisionTableServiceImpl
 * @Description: 决策表Service实现层
 * @author weiyongpeng
 * @date 2024年9月27日 上午10:55:08
 */
@Component
public class RuleDecisionTableServiceImpl implements RuleDecisionTableService {

	private static final Logger logger = LoggerFactory.getLogger(RuleDecisionTableServiceImpl.class);

	@Inject
	private RuleDecisionTableMapper ruleDecisionTableMapper;

	@Override
	public int save(RuleModelDeploy ruleModelDeploy) {
		Date nowDate = DateUtils.getNowDate();
		LoginUser loginUser = SecurityUtil.getLoginUser();
		// 如果前端传递了版本号，则是新增版本，否则就是修改第一次创建规则/修改规则
		if (ruleModelDeploy.getRuleModelVersion() == null || ("null").equals(ruleModelDeploy.getRuleModelVersion())
				|| ("").equals(ruleModelDeploy.getRuleModelVersion())) {
			// 查询规则信息，根据主键ID
			RuleModelDeploy modelTree = findRuleDeployById(ruleModelDeploy);
			if (modelTree != null) { // 存在-修改
				modelTree.setRuleModelName(ruleModelDeploy.getRuleModelName());
				modelTree.setRuleModelValue(ruleModelDeploy.getRuleModelValue());
				modelTree.setRuleRawValue(ruleModelDeploy.getRuleRawValue());
				modelTree.setRuleResValue(ruleModelDeploy.getRuleModelValue());
				modelTree.setUpdateBy(String.valueOf(loginUser.getUserid()));
				modelTree.setUpdateTime(nowDate);
				modelTree.setDelFlag(DictEnum.DEL_FLAG.OK.getValue());
				updateRuleModel(modelTree);
			} else { // 不存在-新增
				ruleModelDeploy.setId("TA" + DateUtils.getNowDate().getTime() + "");
				ruleModelDeploy.setRuleModelKey("key_" + ruleModelDeploy.getId());
				ruleModelDeploy.setRuleModelVersion("1");
				ruleModelDeploy.setCreateTime(nowDate);
				ruleModelDeploy.setUpdateBy(String.valueOf(loginUser.getUserid()));
				ruleModelDeploy.setUpdateTime(nowDate);
				ruleModelDeploy.setStatus(RuleConstants.MODEL_STS_NOT_ENABLE);
				ruleModelDeploy.setRuleType(RuleTypeConstants.decisionTable.getCode()); // 决策表
				ruleModelDeploy.setDelFlag(DictEnum.DEL_FLAG.OK.getValue());
				ruleDecisionTableMapper.insert(ruleModelDeploy);
			}
		} else { // 新增版本
			ruleModelDeploy.setId(new Date().getTime() + "");
			ruleModelDeploy.setRuleModelVersion((getMaxVersionByKey(ruleModelDeploy.getRuleModelKey()) + 1) + "");
			ruleModelDeploy.setCreateTime(nowDate);
			ruleModelDeploy.setUpdateTime(nowDate);
			ruleModelDeploy.setStatus(RuleConstants.MODEL_STS_NOT_ENABLE);
			ruleModelDeploy.setCreateBy(String.valueOf(loginUser.getUserid()));
			ruleModelDeploy.setDelFlag(DictEnum.DEL_FLAG.OK.getValue());
			ruleDecisionTableMapper.insert(ruleModelDeploy);
		}
		return 0;
	}

	@Override
	public RuleModelDeploy findRuleDeployById(RuleModelDeploy ruleModelDeploy) {
		return ruleDecisionTableMapper.selectOneById(ruleModelDeploy.getId());
	}

	private int getMaxVersionByKey(String ruleModelKey) {
		return ruleDecisionTableMapper.findMaxVersionByKey(ruleModelKey);
	}

	@Override
	public int updateRuleModel(RuleModelDeploy ruleModelDeploy) {
		return ruleDecisionTableMapper.update(ruleModelDeploy);
	}

	@Override
	public boolean updateStatus(RuleModelDeploy ruleModelDeploy) {
		try {
			ruleModelDeploy.setUpdateBy(String.valueOf(SecurityUtil.getLoginUser().getUserid()));
			ruleModelDeploy.setUpdateTime(DateUtils.getNowDate());
			if (ruleDecisionTableMapper.updateStatus(ruleModelDeploy) > 0) {
				return true;
			}
			return false;
		} catch (Exception e) {
			logger.error("修改状态失败：{}", e);
			throw new ServiceException("修改状态失败,请联系开发人员检查");
		}
	}

	@Override
	public boolean delete(String id) {
		try {
			if (ruleDecisionTableMapper.delete(id) > 0) {
				return true;
			}
			return false;
		} catch (Exception e) {
			logger.error("删除失败：{}", e);
			throw new ServiceException("删除失败,请联系开发人员检查");
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public DecisionTableResultVo debug(String dataInfo, String decisionTableJson) throws Exception {
		DecisionTable decisionTable = JSON.parseObject(decisionTableJson, DecisionTable.class);
		// 执行日志
		StringBuilder logs = new StringBuilder();
		// 构建执行入参Map
		Map<String,Object> inputMap = com.alibaba.fastjson2.JSONObject.parseObject(dataInfo, Map.class);
		// 执行
		DecisionTableResultVo resultVo = XDecisionTableEngine.doDecisionTable(decisionTable, inputMap, UUID.randomUUID().toString(), logs);
		return resultVo;
	}

	@SuppressWarnings("unchecked")
	@Override
	public DecisionTableResultVo execuateRule(String dataInfo, @NotNull String id, String operateNo) throws Exception {
		DecisionTableResultVo resultVo = new DecisionTableResultVo();
		// 根据ID查询决策表JSON字符串
		String decisionTableJson = ruleDecisionTableMapper.findRuleTableJsonById(id, RuleTypeConstants.decisionTable.getCode());
		if(Optional.ofNullable(decisionTableJson).isPresent()) {
			// 调用引擎执行
			DecisionTable decisionTable = JSON.parseObject(decisionTableJson, DecisionTable.class);
			// 执行日志
			StringBuilder logs = new StringBuilder();
			// 构建执行入参Map
			Map<String,Object> inputMap = com.alibaba.fastjson2.JSONObject.parseObject(dataInfo, Map.class);
			// 执行
			resultVo = XDecisionTableEngine.doDecisionTable(decisionTable, inputMap, UUID.randomUUID().toString(), logs);
			return resultVo;
		}
		return resultVo;
	}

}
